"""
情绪分析智能体

负责市场情绪分析，包括新闻情感分析、市场氛围评估等
"""

from agno.agent import Agent
from ..utils.model_factory import create_model
from typing import Dict, Any, Optional, List
import logging
from datetime import datetime
from ..tools.akshare_client import AkShareClient
from ..tools.llm_client import LLMClient
from ..config.sentiment_prompts import SentimentPrompts
logger = logging.getLogger(__name__)


class SentimentAnalystAgent:
    """情绪分析智能体类"""
    
    def __init__(self, model_id: str = "deepseek-chat"):
        """
        初始化情绪分析智能体
        
        Args:
            model_id: LLM模型ID
        """
        self.akshare_client = AkShareClient()
        self.llm_client = LLMClient()
        # 移除NewsAnalyzer依赖，简化数据处理流程
        
        # 定义情绪分析工具
        def analyze_market_sentiment(agent: Agent, ticker: str, news_count: int = 20) -> str:
            """
            分析市场情绪 - 优化版本，消除重复分析

            Args:
                ticker: 股票代码
                news_count: 分析的新闻数量

            Returns:
                str: 情绪分析结果
            """
            try:
                logger.info(f"开始情绪分析: {ticker}")

                # 检查缓存
                # cache_key = f"{ticker}_{news_count}"
                # cached_result = self._get_cached_sentiment(cache_key)
                # if cached_result:
                #     logger.info(f"使用缓存的情绪分析结果: {ticker}")
                #     return cached_result

                # 获取新闻数据
                news_data = self._load_news_data(ticker)
                if not news_data:
                    return f"无法获取股票 {ticker} 的新闻数据"
                
                # 过滤相关新闻
                relevant_news = self._filter_recent_news(news_data, days_back=30)
                if not relevant_news:
                    return f"未找到股票 {ticker} 的相关新闻"

                # 限制新闻数量
                relevant_news = relevant_news[:news_count]

                # 使用统一的专业A股情感分析（替代多重分析）
                sentiment_result = self._analyze_sentiment_unified(relevant_news, ticker)

                # 生成简洁的分析报告
                report = self._generate_sentiment_report(sentiment_result, ticker, len(relevant_news))

                # 保存到session和缓存
                self._save_sentiment_result(agent, ticker, sentiment_result, len(relevant_news))
                # self._cache_sentiment_result(cache_key, report)

                logger.info(f"情绪分析完成: {ticker}")
                return report

                
            except Exception as e:
                error_msg = f"情绪分析失败: {str(e)}"
                logger.error(error_msg)
                return error_msg
        
        def get_sentiment_summary(agent: Agent) -> str:
            """
            获取情绪分析摘要
            
            Returns:
                str: 情绪分析摘要
            """
            if "sentiment_analysis" not in agent.session_state:
                return "尚未进行任何情绪分析"
            
            analyses = agent.session_state["sentiment_analysis"]
            summary_lines = ["情绪分析摘要:"]
            
            for ticker, data in analyses.items():
                analysis = data.get("analysis", {})
                signal = analysis.get("signal", "unknown")
                confidence = analysis.get("confidence", 0)
                sentiment_score = analysis.get("sentiment_score", 0)
                news_count = data.get("news_analyzed", 0)
                analysis_time = data.get("analysis_time", "unknown")
                
                signal_emoji = "😊" if signal == "bullish" else "😟" if signal == "bearish" else "😐"
                summary_lines.append(
                    f"- {ticker}: {signal_emoji} {signal.upper()} "
                    f"(分数: {sentiment_score:.2f}, 置信度: {confidence:.1%}, 新闻: {news_count}条) [{analysis_time}]"
                )
            
            return "\n".join(summary_lines)
        
        def compare_market_sentiment(agent: Agent, tickers: str) -> str:
            """
            比较多个股票的市场情绪
            
            Args:
                tickers: 股票代码列表，用逗号分隔
                
            Returns:
                str: 情绪比较结果
            """
            ticker_list = [t.strip() for t in tickers.split(",")]
            
            if "sentiment_analysis" not in agent.session_state:
                return "尚未进行任何情绪分析，请先分析相关股票"
            
            analyses = agent.session_state["sentiment_analysis"]
            comparison_lines = ["市场情绪比较:"]
            
            positive_stocks = []
            negative_stocks = []
            neutral_stocks = []
            
            for ticker in ticker_list:
                if ticker in analyses:
                    analysis = analyses[ticker]["analysis"]
                    signal = analysis.get("signal", "neutral")
                    sentiment_score = analysis.get("sentiment_score", 0)
                    confidence = analysis.get("confidence", 0)
                    
                    stock_info = f"{ticker} (分数: {sentiment_score:.2f}, 置信度: {confidence:.1%})"
                    
                    if signal == "bullish":
                        positive_stocks.append(stock_info)
                    elif signal == "bearish":
                        negative_stocks.append(stock_info)
                    else:
                        neutral_stocks.append(stock_info)
                else:
                    neutral_stocks.append(f"{ticker} (未分析)")
            
            if positive_stocks:
                comparison_lines.append(f"😊 积极情绪: {', '.join(positive_stocks)}")
            if negative_stocks:
                comparison_lines.append(f"😟 消极情绪: {', '.join(negative_stocks)}")
            if neutral_stocks:
                comparison_lines.append(f"😐 中性情绪: {', '.join(neutral_stocks)}")
            
            return "\n".join(comparison_lines)
        
        def analyze_news_themes(agent: Agent, ticker: str) -> str:
            """
            分析新闻主题趋势
            
            Args:
                ticker: 股票代码
                
            Returns:
                str: 主题分析结果
            """
            if "sentiment_analysis" not in agent.session_state:
                return "尚未进行情绪分析，请先分析相关股票"
            
            analyses = agent.session_state["sentiment_analysis"]
            if ticker not in analyses:
                return f"尚未分析股票 {ticker} 的情绪，请先进行情绪分析"
            
            analysis_data = analyses[ticker]["analysis"]
            key_themes = analysis_data.get("key_themes", [])
            sentiment_score = analysis_data.get("sentiment_score", 0)
            
            if not key_themes:
                return f"股票 {ticker} 没有发现明显的新闻主题"
            
            theme_lines = [f"{ticker} 新闻主题分析:"]
            theme_lines.append(f"整体情绪倾向: {'积极' if sentiment_score > 0.1 else '消极' if sentiment_score < -0.1 else '中性'} ({sentiment_score:.2f})")
            theme_lines.append("\n主要讨论主题:")
            
            for i, theme in enumerate(key_themes[:10], 1):
                theme_lines.append(f"{i}. {theme}")
            
            return "\n".join(theme_lines)
        
        # 创建Agno智能体
        self.agent = Agent(
            name="Sentiment Analyst Agent",
            role="市场情绪分析专家",
            model=create_model(model_id),
            tools=[analyze_market_sentiment, get_sentiment_summary, compare_market_sentiment, analyze_news_themes],
            session_state={"sentiment_analysis": {}},
            instructions="\n".join(SentimentPrompts.get_enhanced_agent_instructions()),
            add_state_in_messages=True,
            show_tool_calls=True,
            markdown=True
        )
        
        logger.info("情绪分析智能体初始化完成")

    # def _get_cached_sentiment(self, cache_key: str) -> Optional[str]:
    #     """获取缓存的情绪分析结果"""
    #     try:
    #         import json
    #         import os
    #         from datetime import datetime, timedelta

    #         cache_file = "data/sentiment_cache.json"
    #         if not os.path.exists(cache_file):
    #             return None

    #         with open(cache_file, 'r', encoding='utf-8') as f:
    #             cache = json.load(f)

    #         if cache_key in cache:
    #             cached_data = cache[cache_key]
    #             # 检查缓存是否过期（1小时）
    #             cache_time = datetime.fromisoformat(cached_data.get("timestamp", ""))
    #             if datetime.now() - cache_time < timedelta(hours=1):
    #                 return cached_data.get("result")

    #     except Exception as e:
    #         logger.warning(f"读取缓存失败: {e}")
    #     return None

    # def _cache_sentiment_result(self, cache_key: str, result: str):
    #     """缓存情绪分析结果"""
    #     try:
    #         import json
    #         import os
    #         from datetime import datetime

    #         cache_file = "data/sentiment_cache.json"
    #         os.makedirs(os.path.dirname(cache_file), exist_ok=True)

    #         # 读取现有缓存
    #         cache = {}
    #         if os.path.exists(cache_file):
    #             try:
    #                 with open(cache_file, 'r', encoding='utf-8') as f:
    #                     cache = json.load(f)
    #             except:
    #                 cache = {}

    #         # 添加新缓存
    #         cache[cache_key] = {
    #             "result": result,
    #             "timestamp": datetime.now().isoformat()
    #         }

    #         # 保存缓存
    #         with open(cache_file, 'w', encoding='utf-8') as f:
    #             json.dump(cache, f, ensure_ascii=False, indent=2)

    #     except Exception as e:
    #         logger.warning(f"保存缓存失败: {e}")

    def _load_news_data(self, ticker: str) -> List:
        """加载新闻数据"""
        try:
            import json
            import os
            from ..models.market_data import NewsItem

            data_dir = "data/collected_data"
            filename = f"market_data_agent_data_{ticker}_latest.json"
            file_path = os.path.join(data_dir, filename)

            if not os.path.exists(file_path):
                return []

            with open(file_path, "r") as f:
                collected_data = json.load(f)

            news_data_list = collected_data.get("summary", {}).get("news_data", [])
            return [NewsItem(**news_item) for news_item in news_data_list]

        except Exception as e:
            logger.error(f"加载新闻数据失败: {e}")
            return []

    def _filter_recent_news(self, news_data: List, days_back: int = 7) -> List:
        """过滤最近的新闻"""
        try:
            from datetime import datetime, timedelta

            cutoff_date = datetime.now() - timedelta(days=days_back)
            recent_news = []

            for news in news_data:
                if hasattr(news, 'publish_time') and news.publish_time:
                    if isinstance(news.publish_time, str):
                        try:
                            news_time = datetime.fromisoformat(news.publish_time.replace('Z', '+00:00'))
                        except:
                            continue
                    else:
                        news_time = news.publish_time

                    if news_time > cutoff_date:
                        recent_news.append(news)

            # 按时间排序，最新的在前
            recent_news.sort(key=lambda x: x.publish_time, reverse=True)
            return recent_news

        except Exception as e:
            logger.error(f"过滤新闻失败: {e}")
            return news_data[:20]  # 返回前20条作为备用

    def _analyze_sentiment_unified(self, news_data: List, ticker: str) -> Dict[str, Any]:
        """统一的情绪分析方法"""
        try:
            # 构建新闻内容用于LLM分析
            news_content = self._build_news_content_for_llm(news_data)

            # 使用专业A股情感分析
            system_prompt = SentimentPrompts.get_professional_a_share_system_prompt()

            user_prompt = f"""请分析以下A股上市公司相关新闻的情感倾向：

{news_content}

请直接返回一个数字，范围是-1到1，无需解释。"""

            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt}
            ]

            # 调用LLM获取情感分数
            response = self.llm_client.chat_completion(messages, temperature=0.3)
            # print(response)
            # print('-'*100)

            # 解析情感分数
            try:
                sentiment_score = float(response.strip())
                sentiment_score = max(-1.0, min(1.0, sentiment_score))
            except ValueError:
                logger.warning(f"无法解析情感分数: {response}")
                sentiment_score = 0.0

            # 生成信号和置信度
            if sentiment_score >= 0.5:
                signal = "bullish"
                confidence = abs(sentiment_score)
            elif sentiment_score <= -0.5:
                signal = "bearish"
                confidence = abs(sentiment_score)
            else:
                signal = "neutral"
                confidence = 1.0 - abs(sentiment_score*2)

            return {
                "sentiment_score": sentiment_score,
                "signal": signal,
                "confidence": confidence,
                "reasoning": f"基于 {len(news_data)} 条新闻分析，情感分数: {sentiment_score:.2f}，范围是-1到1，-1是消极，1是积极，0是中性，负数偏消极，正数偏积极"
            }

        except Exception as e:
            logger.error(f"统一情绪分析失败: {e}")
            return {
                "sentiment_score": 0.0,
                "signal": "neutral",
                "confidence": 0.0,
                "reasoning": f"分析失败: {str(e)}"
            }

    def _build_news_content_for_llm(self, news_data: List) -> str:
        """为LLM构建新闻内容"""
        news_content = ""
        for i, news in enumerate(news_data[:10], 1):  # 最多10条新闻
            title = getattr(news, 'title', '无标题')
            content = getattr(news, 'content', '') or ''
            publish_time = getattr(news, 'publish_time', '')
            source = getattr(news, 'source', '')

            news_content += f"标题：{title}\n"
            if source:
                news_content += f"来源：{source}\n"
            if publish_time:
                news_content += f"时间：{publish_time}\n"
            if content:
                # 限制内容长度
                content = content[:300] if len(content) > 300 else content
                news_content += f"内容：{content}\n"
            news_content += "\n"

        return news_content

    def _generate_sentiment_report(self, sentiment_result: Dict[str, Any], ticker: str, news_count: int) -> str:
        """生成简洁的情绪分析报告"""
        sentiment_score = sentiment_result.get("sentiment_score", 0.0)
        signal = sentiment_result.get("signal", "neutral")
        confidence = sentiment_result.get("confidence", 0.0)
        reasoning = sentiment_result.get("reasoning", "")

        # 情绪描述
        if sentiment_score >= 0.5:
            mood_desc = "积极乐观"
            emoji = "😊"
        elif sentiment_score <= -0.5:
            mood_desc = "消极悲观"
            emoji = "😟"
        else:
            mood_desc = "中性平稳"
            emoji = "😐"

        # 投资建议
        if signal == "bullish":
            advice = "可考虑适当关注，但需结合技术面分析"
        elif signal == "bearish":
            advice = "建议谨慎，关注风险控制"
        else:
            advice = "保持观望，等待更明确信号"

        report = f"""A股市场情绪分析报告 - {ticker}

{emoji} **整体情绪**: {mood_desc}
**情绪分数**: {sentiment_score:.2f} (-1到1之间)
**交易信号**: {signal.upper()}
**置信度**: {confidence:.1%}

**分析依据**
{reasoning}

**投资建议**
{advice}

**风险提示**
投资有风险，入市需谨慎。本分析仅供参考，不构成投资建议。

**分析信息**
- 分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
- 新闻数量: {news_count} 条
- 分析方法: 专业A股情感分析"""

        return report

    def _save_sentiment_result(self, agent: Agent, ticker: str, sentiment_result: Dict[str, Any], news_count: int):
        """保存情绪分析结果到session"""
        if "sentiment_analysis" not in agent.session_state:
            agent.session_state["sentiment_analysis"] = {}

        agent.session_state["sentiment_analysis"][ticker] = {
            "analysis": sentiment_result,
            "news_analyzed": news_count,
            "analysis_time": datetime.now().isoformat()
        }

    def run(self, message: str, **kwargs) -> str:
        """运行智能体"""
        try:
            response = self.agent.run(message, **kwargs)
            # 正确处理RunResponse对象
            if response:
                if hasattr(response, 'content'):
                    return str(response.content) if response.content else "执行失败，未收到响应内容"
                else:
                    return str(response) if response else "执行失败，响应为空"
            else:
                return "执行失败，未收到响应"
        except Exception as e:
            error_msg = f"情绪分析智能体执行失败: {str(e)}"
            logger.error(error_msg)
            return error_msg
    
    def print_response(self, message: str, stream: bool = True, **kwargs):
        """打印智能体响应"""
        self.agent.print_response(message, stream=stream, **kwargs)

    def get_analysis_result(self, ticker: str) -> Optional[Dict[str, Any]]:
        """获取情绪分析结果"""
        return self.agent.session_state.get("sentiment_analysis", {}).get(ticker)
